using System.Collections.Generic;
using System.Diagnostics.Contracts;

namespace DataStore.Repositories
{
    /// <summary>
    /// Base interface for repositories
    /// </summary>
    /// <typeparam name="T">Type of the entity the repository serves</typeparam>
    [ContractClass(typeof(IRepositoryContract<>))]
    public interface IRepository<T> where T: class
    {
        T Get(object id);
        void Delete(T entity);
        void DeleteAll();
        void Save(T entity);
        T SaveOrUpdate(T entity);
        void Update(T entity);
        IEnumerable<T> All { get; }
        bool Exists(T entity);
        bool IsEmpty { get; }
        int Count(T entity);
        int CountAll();

    }

    /// <summary>
    /// Contract class for IRepository
    /// </summary>
    /// <typeparam name="T">Type of the entity the repository serves</typeparam>
    [ContractClassFor(typeof(IRepository<>))]
    sealed class IRepositoryContract<T> : IRepository<T> where T:class
    {

        #region IRepository<T> Members

        T IRepository<T>.Get(object id)
        {
            Contract.Requires(id != null);
            return default(T);
        }

        void IRepository<T>.Delete(T entity)
        {
            Contract.Requires(entity != null);
        }

        void IRepository<T>.DeleteAll()
        {
            throw new System.NotImplementedException();
        }

        void IRepository<T>.Save(T entity)
        {
            Contract.Requires(entity != null);
        }

        T IRepository<T>.SaveOrUpdate(T entity)
        {
            Contract.Requires(entity != null);
            return default(T);
        }

        void IRepository<T>.Update(T entity)
        {
            Contract.Requires(entity != null);
        }

        IEnumerable<T> IRepository<T>.All
        {
            get { throw new System.NotImplementedException(); }
        }

        bool IRepository<T>.Exists(T entity)
        {
            Contract.Requires(entity != null);
            return default(bool);
        }

        bool IRepository<T>.IsEmpty
        {
            get { throw new System.NotImplementedException(); }
        }

        int IRepository<T>.Count(T entity)
        {
            Contract.Requires(entity != null);
            return default(int);
        }

        int IRepository<T>.CountAll()
        {
            throw new System.NotImplementedException();
        }

        #endregion
    }
}